package emulator.GUI.io;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

import emulator.hardware.io.Via6522;
import emulator.shell.GUI.menu.ViaRegistersDialog;

@SuppressWarnings("serial")
public class Via6522panel extends JPanel 
{
	private Via6522 via;
	private TimerPanel timer1panel = new TimerPanel("Timer 1", new String [] { "Timed interrupt on load", "Continuous interrupts", "Timed interrupt on load, one-shot output on PB7", "Continuous interrupts, square wave on PB7" });
	private TimerPanel timer2panel = new TimerPanel("Timer 2", new String [] { "Timed interrupt", "Count-down through PB6" });
	private ShiftPanel shiftpanel = new ShiftPanel("Shift", 
			new String [] { "Disabled", 
							"Shift in under control of T2",
							"Shift in under control of O2",
							"Shift in under control of ext. clock",
							"Shift out free-running at T2 rate",
							"Shift out under control of T2",
							"Shift out under control of O2",
							"Shift out under control of ext. clock" });
	private PortPanel portApanel = new PortPanel("A");
	private PortPanel portBpanel = new PortPanel("B");
	private IrqPanel irqPanel = new IrqPanel();
	private String viaName;
	
	public Via6522panel(Via6522 via, String viaName)
	{
		super();
		this.via = via;
		this.viaName = viaName;
		initPanel();
	}

	public void updateFromVia()
	{
		timer1panel.setLatchValue(via.getTimer1Latch());
		timer1panel.setTimerValue(via.getTimer1Counter());
		timer1panel.setModeValue(via.getTimer1Mode());
		timer2panel.setLatchValue(via.getTimer2Latch());
		timer2panel.setTimerValue(via.getTimer2Counter());
		timer2panel.setModeValue(via.getTimer2Mode());
		shiftpanel.setLatchValue(via.getShiftRegister());
		shiftpanel.setShiftValue(via.getShiftRegister());
		shiftpanel.setModeValue(via.getShiftMode());
		irqPanel.setFlagsValue(via.readIFR());
		irqPanel.setMaskValue(via.readIER());
		portApanel.setPortStatus(via.getPortA());
		portApanel.setPortControlModes(via.getCA1Mode(), via.getCA2Mode());
		portBpanel.setPortStatus(via.getPortB());
		portBpanel.setPortControlModes(via.getCB1Mode(), via.getCB2Mode());
	}

	private void initPanel()
	{
		JPanel regPanel = new JPanel();
		regPanel.setLayout(new BoxLayout(regPanel, BoxLayout.PAGE_AXIS));
		regPanel.add(timer1panel);
		regPanel.add(timer2panel);
		regPanel.add(Box.createRigidArea(new Dimension(0, 10)));
		regPanel.add(shiftpanel);
		regPanel.add(Box.createRigidArea(new Dimension(0, 10)));
		regPanel.add(irqPanel);
		regPanel.add(Box.createRigidArea(new Dimension(0, 10)));
		regPanel.add(Box.createVerticalGlue());
		JButton registersButton = new JButton("Register values...");
		registersButton.addActionListener(new OpenRegistersDialog());
		regPanel.add(registersButton);
		regPanel.add(Box.createRigidArea(new Dimension(0, 5)));
		
		JPanel portPanel = new JPanel();
		portPanel.setLayout(new BoxLayout(portPanel, BoxLayout.PAGE_AXIS));
		portPanel.add(portApanel);
		portPanel.add(portBpanel);
		
		setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
		add(regPanel);
		add(portPanel);
	}

	public class OpenRegistersDialog implements ActionListener
	{

		@Override
		public void actionPerformed(ActionEvent e)
		{
			ViaRegistersDialog registersDialog = new ViaRegistersDialog(null, "Registers", viaName);
			for (int i = 0; i < 16; i++)
				try {
					registersDialog.setRegisterValue(i, via.read(i));
				} catch (Exception ex) { ex.printStackTrace(); }
			registersDialog.setVisible(true);
			if (registersDialog.isResultValid())
			{
				for (int i = 0; i < 16; i++)
					try {
						via.write(i, registersDialog.getRegisterValue(i));
					} catch (Exception ex) { ex.printStackTrace(); }
				updateFromVia();
			}
		}
	}
}
